<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title><%= tilesetId %></title>
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <script src="/api/assets/mapbox-gl.js"></script>
  <link rel="stylesheet" href="/api/assets/mapbox-gl.css">
  <style>
    html, body, #map {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
    }

    #menu {
      position: absolute;
      top: 20px;
      left: 20px;
      width: 200px;
      box-sizing: border-box;
      padding: 20px;
      background-color: #fff;
    }

    .popup {
      color: #333;
      display: table;
      font-size: 14px;
    }

    .feature:not(:last-child) {
      border-bottom: 1px solid #ccc;
    }

    .layer:before {
      content: '#';
    }

    .layer {
      display: block;
      font-weight: bold;
    }

    .property {
      display: table-row;
    }

    .property-key {
      display: table-cell;
      padding-right: 10px;
    }

    .property-value {
      display: table-cell;
    }
  </style>
</head>
<body>
  <div id="map"></div>

  <div id="menu">
    <input id="show-attributes" type="checkbox">
    <label for="show-attributes">显示属性</label>
  </div>

  <script>
    fetch('./tilejson')
      .then(response => response.json())
      .then(tilejson => {
        const style = {
          version: 8,
          sources: {
            source: {
              type: 'vector',
              url: './tilejson'
            }
          },
          layers: [{
            id: 'background',
            type: 'background',
            paint: {
              'background-color': 'hsl(55, 1%, 20%)'
            }
          }]
        }

        tilejson.vector_layers.forEach(layer => {
          const color = getColor()
          const layers = [
            {
              id: layer.id + '-polygon',
              type: 'fill',
              source: 'source',
              'source-layer': layer.id,
              filter: ['==', '$type', 'Polygon'],
              paint: {
                'fill-color': color,
                'fill-opacity': 0.1
              }
            },
            {
              id: layer.id + '-polygon-outline',
              type: 'line',
              source: 'source',
              'source-layer': layer.id,
              filter: ['==', '$type', 'Polygon'],
              layout: {
                'line-join': 'round',
                'line-cap': 'round'
              },
              paint: {
                'line-color': color,
                'line-width': 1,
                'line-opacity': 0.75
              }
            },
            {
              id: layer.id + '-line',
              type: 'line',
              source: 'source',
              'source-layer': layer.id,
              filter: ['==', '$type', 'LineString'],
              layout: {
                'line-join': 'round',
                'line-cap': 'round'
              },
              paint: {
                'line-color': color,
                'line-width': 1,
                'line-opacity': 0.75
              }
            },
            {
              id: layer.id + '-point',
              type: 'circle',
              source: 'source',
              'source-layer': layer.id,
              filter: ['==', '$type', 'Point'],
              paint: {
                'circle-color': color,
                'circle-radius': 2.5,
                'circle-opacity': 0.75
              }
            }
          ]

          style.layers = style.layers.concat(layers)
        })

        const center = tilejson.center || [0, 0, 1]

        var map = new mapboxgl.Map({
          container: 'map',
          attributionControl: false,
          style,
          center: [center[0], center[1]],
          zoom: center[2],
          hash: true
        })

        map.addControl(new mapboxgl.NavigationControl())
        map.addControl(new mapboxgl.FullscreenControl())
        map.addControl(new mapboxgl.ScaleControl())
        map.showTileBoundaries = true

        const popup = new mapboxgl.Popup({
          closeButton: false,
          closeOnClick: false
        })

        const input = document.getElementById('show-attributes')
        map.on('mousemove', e => {
          if (!input.checked) return

          const features = map.queryRenderedFeatures(e.point) || []
          map.getCanvas().style.cursor = (features.length) ? 'pointer' : ''
          if(!features.length) return popup.remove()

          popup.setLngLat(e.lngLat)
            .setHTML(renderPopup(features))
            .addTo(map)
        })

        input.addEventListener('change', e => {
          if (!e.target.checked) return popup.remove()
        })
      })

      let i = 0
      function getColor() {
        const colors = [
          '#FC49A3', // pink
          '#CC66FF', // purple-ish
          '#66CCFF', // sky blue
          '#66FFCC', // teal
          '#00FF00', // lime green
          '#FFCC66', // light orange
          '#FF6666', // salmon
          '#FF0000', // red
          '#FF8000', // orange
          '#FFFF66', // yellow
          '#00FFFF'  // turquoise
        ]

        const color = colors[i]
        i = (i + 1) % colors.length

        return color
      }

      function renderPopup(features) {
        return `
          <div class="popup">
            ${features.map(feature => `
              <div id="feature">${renderFeature(feature)}</div>
            `).join('')}
          </div>
        `
      }

      function renderFeature(feature) {
        const sourceLayer = feature.layer['source-layer'] || feature.layer.source
        const properties = []
        if (feature.id) properties.push(['$id', feature.id])
        properties.push(['$type', feature.geometry.type])
        Object.keys(feature.properties).forEach(key => {
          properties.push([key, feature.properties[key]])
        })

        return `
          <div class="layer">${sourceLayer}</div>
          ${properties.map(property => `
            <div class="property">
              <div class="property-key">${property[0]}</div>
              <div class="property-value">${property[1]}</div>
            </div>
            `).join('')
          }
        `
      }
  </script>
</body>
</html>
